home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Games Extra 1996 September
/
Amiga Games Extra CD-ROM 9-1996.iso
/
userbox
/
publicdomain
/
vim-4.2
/
src
/
tables.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-09
|
13KB
|
478 lines
/* vi:set ts=4 sw=4:
*
* VIM - Vi IMproved by Bram Moolenaar
* This file by Robert Webb
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
*/
/*
* tables.c: functions that use lookup tables for various things, generally to
* do with special key codes.
*/
#include "vim.h"
#include "globals.h"
#include "proto.h"
#include "option.h"
/*
* Some useful tables.
*/
static struct
{
int mod_mask; /* Bit-mask for particular key modifier */
char_u name; /* Single letter name of modifier */
} mod_mask_table[] =
{
{MOD_MASK_ALT, (char_u)'M'},
{MOD_MASK_CTRL, (char_u)'C'},
{MOD_MASK_SHIFT, (char_u)'S'},
{MOD_MASK_2CLICK, (char_u)'2'},
{MOD_MASK_3CLICK, (char_u)'3'},
{MOD_MASK_4CLICK, (char_u)'4'},
{0x0, NUL}
};
/*
* Shifted key terminal codes and their unshifted equivalent.
* Don't add mouse codes here, they are handled seperately!
*/
static char_u shifted_keys_table[] =
{
/* shifted unshifted */
'&', '9', '@', '1', /* begin */
'&', '0', '@', '2', /* cancel */
'*', '1', '@', '4', /* command */
'*', '2', '@', '5', /* copy */
'*', '3', '@', '6', /* create */
'*', '4', 'k', 'D', /* delete char */
'*', '5', 'k', 'L', /* delete line */
'*', '7', '@', '7', /* end */
'*', '9', '@', '9', /* exit */
'*', '0', '@', '0', /* find */
'#', '1', '%', '1', /* help */
'#', '2', 'k', 'h', /* home */
'#', '3', 'k', 'I', /* insert */
'#', '4', 'k', 'l', /* left arrow */
'%', 'a', '%', '3', /* message */
'%', 'b', '%', '4', /* move */
'%', 'c', '%', '5', /* next */
'%', 'd', '%', '7', /* options */
'%', 'e', '%', '8', /* previous */
'%', 'f', '%', '9', /* print */
'%', 'g', '%', '0', /* redo */
'%', 'h', '&', '3', /* replace */
'%', 'i', 'k', 'r', /* right arrow */
'%', 'j', '&', '5', /* resume */
'!', '1', '&', '6', /* save */
'!', '2', '&', '7', /* suspend */
'!', '3', '&', '8', /* undo */
KS_EXTRA, KE_S_UP, 'k', 'u', /* up arrow */
KS_EXTRA, KE_S_DOWN, 'k', 'd', /* down arrow */
KS_EXTRA, KE_S_F1, 'k', '1', /* F1 */
KS_EXTRA, KE_S_F2, 'k', '2',
KS_EXTRA, KE_S_F3, 'k', '3',
KS_EXTRA, KE_S_F4, 'k', '4',
KS_EXTRA, KE_S_F5, 'k', '5',
KS_EXTRA, KE_S_F6, 'k', '6',
KS_EXTRA, KE_S_F7, 'k', '7',
KS_EXTRA, KE_S_F8, 'k', '8',
KS_EXTRA, KE_S_F9, 'k', '9',
KS_EXTRA, KE_S_F10, 'k', ';', /* F10 */
KS_EXTRA, KE_S_F11, 'F', '1',
KS_EXTRA, KE_S_F12, 'F', '2',
KS_EXTRA, KE_S_F13, 'F', '3',
KS_EXTRA, KE_S_F14, 'F', '4',
KS_EXTRA, KE_S_F15, 'F', '5',
KS_EXTRA, KE_S_F16, 'F', '6',
KS_EXTRA, KE_S_F17, 'F', '7',
KS_EXTRA, KE_S_F18, 'F', '8',
KS_EXTRA, KE_S_F19, 'F', '9',
KS_EXTRA, KE_S_F20, 'F', 'A',
KS_EXTRA, KE_S_F21, 'F', 'B',
KS_EXTRA, KE_S_F22, 'F', 'C',
KS_EXTRA, KE_S_F23, 'F', 'D',
KS_EXTRA, KE_S_F24, 'F', 'E',
KS_EXTRA, KE_S_F25, 'F', 'F',
KS_EXTRA, KE_S_F26, 'F', 'G',
KS_EXTRA, KE_S_F27, 'F', 'H',
KS_EXTRA, KE_S_F28, 'F', 'I',
KS_EXTRA, KE_S_F29, 'F', 'J',
KS_EXTRA, KE_S_F30, 'F', 'K',
KS_EXTRA, KE_S_F31, 'F', 'L',
KS_EXTRA, KE_S_F32, 'F', 'M',
KS_EXTRA, KE_S_F33, 'F', 'N',
KS_EXTRA, KE_S_F34, 'F', 'O',
KS_EXTRA, KE_S_F35, 'F', 'P',
KS_EXTRA, KE_S_TAB, KS_EXTRA, KE_TAB, /* TAB */
NUL
};
static struct key_name_entry
{
int key; /* Special key code or ascii value */
char_u *name; /* Name of key */
} key_names_table[] =
{
{' ', (char_u *)"Space"},
{TAB, (char_u *)"Tab"},
{K_TAB, (char_u *)"Tab"},
{NL, (char_u *)"NL"},
{NL, (char_u *)"NewLine"}, /* Alternative name */
{NL, (char_u *)"LineFeed"}, /* Alternative name */
{NL, (char_u *)"LF"}, /* Alternative name */
{CR, (char_u *)"CR"},
{CR, (char_u *)"Return"}, /* Alternative name */
{ESC, (char_u *)"Esc"},
{K_UP, (char_u *)"Up"},
{K_DOWN, (char_u *)"Down"},
{K_LEFT, (char_u *)"Left"},
{K_RIGHT, (char_u *)"Right"},
{K_F1, (char_u *)"F1"},
{K_F2, (char_u *)"F2"},
{K_F3, (char_u *)"F3"},
{K_F4, (char_u *)"F4"},
{K_F5, (char_u *)"F5"},
{K_F6, (char_u *)"F6"},
{K_F7, (char_u *)"F7"},
{K_F8, (char_u *)"F8"},
{K_F9, (char_u *)"F9"},
{K_F10, (char_u *)"F10"},
{K_F11, (char_u *)"F11"},
{K_F12, (char_u *)"F12"},
{K_F13, (char_u *)"F13"},
{K_F14, (char_u *)"F14"},
{K_F15, (char_u *)"F15"},
{K_F16, (char_u *)"F16"},
{K_F17, (char_u *)"F17"},
{K_F18, (char_u *)"F18"},
{K_F19, (char_u *)"F19"},
{K_F20, (char_u *)"F20"},
{K_F21, (char_u *)"F21"},
{K_F22, (char_u *)"F22"},
{K_F23, (char_u *)"F23"},
{K_F24, (char_u *)"F24"},
{K_F25, (char_u *)"F25"},
{K_F26, (char_u *)"F26"},
{K_F27, (char_u *)"F27"},
{K_F28, (char_u *)"F28"},
{K_F29, (char_u *)"F29"},
{K_F30, (char_u *)"F30"},
{K_F31, (char_u *)"F31"},
{K_F32, (char_u *)"F32"},
{K_F33, (char_u *)"F33"},
{K_F34, (char_u *)"F34"},
{K_F35, (char_u *)"F35"},
{K_HELP, (char_u *)"Help"},
{K_UNDO, (char_u *)"Undo"},
{K_BS, (char_u *)"BS"},
{K_BS, (char_u *)"BackSpace"}, /* Alternative name */
{K_INS, (char_u *)"Insert"},
{K_INS, (char_u *)"Ins"}, /* Alternative name */
{K_DEL, (char_u *)"Del"},
{K_DEL, (char_u *)"Delete"}, /* Alternative name */
{K_HOME, (char_u *)"Home"},
{K_END, (char_u *)"End"},
{K_PAGEUP, (char_u *)"PageUp"},
{K_PAGEDOWN, (char_u *)"PageDown"},
{K_MOUSE, (char_u *)"Mouse"},
{K_LEFTMOUSE, (char_u *)"LeftMouse"},
{K_LEFTDRAG, (char_u *)"LeftDrag"},
{K_LEFTRELEASE, (char_u *)"LeftRelease"},
{K_MIDDLEMOUSE, (char_u *)"MiddleMouse"},
{K_MIDDLEDRAG, (char_u *)"MiddleDrag"},
{K_MIDDLERELEASE, (char_u *)"MiddleRelease"},
{K_RIGHTMOUSE, (char_u *)"RightMouse"},
{K_RIGHTDRAG, (char_u *)"RightDrag"},
{K_RIGHTRELEASE, (char_u *)"RightRelease"},
{K_ZERO, (char_u *)"Nul"},
{0, NULL}
};
#define KEY_NAMES_TABLE_LEN (sizeof(key_names_table) / sizeof(struct key_name_entry))
#ifdef USE_MOUSE
static struct
{
int pseudo_code; /* Code for pseudo mouse event */
int button; /* Which mouse button is it? */
int is_click; /* Is it a mouse button click event? */
int is_drag; /* Is it a mouse drag event? */
} mouse_table[] =
{
{KE_LEFTMOUSE, MOUSE_LEFT, TRUE, FALSE},
{KE_LEFTDRAG, MOUSE_LEFT, FALSE, TRUE},
{KE_LEFTRELEASE, MOUSE_LEFT, FALSE, FALSE},
{KE_MIDDLEMOUSE, MOUSE_MIDDLE, TRUE, FALSE},
{KE_MIDDLEDRAG, MOUSE_MIDDLE, FALSE, TRUE},
{KE_MIDDLERELEASE, MOUSE_MIDDLE, FALSE, FALSE},
{KE_RIGHTMOUSE, MOUSE_RIGHT, TRUE, FALSE},
{KE_RIGHTDRAG, MOUSE_RIGHT, FALSE, TRUE},
{KE_RIGHTRELEASE, MOUSE_RIGHT, FALSE, FALSE},
{KE_IGNORE, MOUSE_RELEASE, FALSE, TRUE}, /* DRAG without CLICK */
{KE_IGNORE, MOUSE_RELEASE, FALSE, FALSE}, /* RELEASE without CLICK */
{0, 0, 0, 0},
};
#endif /* USE_MOUSE */
/*
* Return the modifier mask bit (MOD_MASK_*) which corresponds to the given
* modifier name ('S' for Shift, 'C' for Ctrl etc).
*/
int
name_to_mod_mask(c)
int c;
{
int i;
for (i = 0; mod_mask_table[i].mod_mask; i++)
if (TO_LOWER(c) == TO_LOWER(mod_mask_table[i].name))
return mod_mask_table[i].mod_mask;
return 0x0;
}
/*
* Decide whether the given key code (K_*) is a shifted special
* key (by looking at mod_mask). If it is, then return the appropriate shifted
* key code, otherwise just return the character as is.
*/
int
check_shifted_spec_key(c)
int c;
{
int i;
int key0;
int key1;
if (mod_mask & MOD_MASK_SHIFT)
{
if (c == TAB) /* TAB is not in the table, K_TAB is */
return K_S_TAB;
key0 = KEY2TERMCAP0(c);
key1 = KEY2TERMCAP1(c);
for (i = 0; shifted_keys_table[i] != NUL; i += 4)
if (key0 == shifted_keys_table[i + 2] &&
key1 == shifted_keys_table[i + 3])
return TERMCAP2KEY(shifted_keys_table[i],
shifted_keys_table[i + 1]);
}
return c;
}
/*
* Decide whether the given special key is shifted or not. If it is we
* return OK and change it to the equivalent unshifted special key code,
* otherwise we leave it as is and return FAIL.
*/
int
unshift_special_key(p)
char_u *p;
{
int i;
for (i = 0; shifted_keys_table[i]; i += 4)
if (p[0] == shifted_keys_table[i] && p[1] == shifted_keys_table[i + 1])
{
p[0] = shifted_keys_table[i + 2];
p[1] = shifted_keys_table[i + 3];
return OK;
}
return FAIL;
}
/*
* Return a string which contains the name of the given key when the given
* modifiers are down.
*/
char_u *
get_special_key_name(c, modifiers)
int c;
int modifiers;
{
static char_u string[MAX_KEY_NAME_LEN + 1];
int i, idx;
char_u *s;
char_u name[2];
string[0] = '<';
idx = 1;
/* translate shifted keys into unshifted keys and set modifier */
if (IS_SPECIAL(c))
{
name[0] = KEY2TERMCAP0(c);
name[1] = KEY2TERMCAP1(c);
if (unshift_special_key(&name[0]))
modifiers |= MOD_MASK_SHIFT;
c = TERMCAP2KEY(name[0], name[1]);
}
/* translate the modifier into a string */
for (i = 0; mod_mask_table[i].mod_mask; i++)
if (modifiers & mod_mask_table[i].mod_mask)
{
string[idx++] = mod_mask_table[i].name;
string[idx++] = (char_u)'-';
}
/* try to find the key in the special key table */
i = find_special_key_in_table(c);
if (i < 0) /* unknown special key, output t_xx */
{
if (IS_SPECIAL(c))
{
string[idx++] = 't';
string[idx++] = '_';
string[idx++] = KEY2TERMCAP0(c);
string[idx++] = KEY2TERMCAP1(c);
}
/* Not a special key, only modifiers, output directly */
else
{
if (isprintchar(c))
string[idx++] = c;
else
{
s = transchar(c);
while (*s)
string[idx++] = *s++;
}
}
}
else /* use name of special key */
{
STRCPY(string + idx, key_names_table[i].name);
idx = STRLEN(string);
}
string[idx++] = '>';
string[idx] = NUL;
return string;
}
/*
* Try to find key "c" in the special key table.
* Return the index when found, -1 when not found.
*/
int
find_special_key_in_table(c)
int c;
{
int i;
for (i = 0; key_names_table[i].name != NULL; i++)
if (c == key_names_table[i].key)
break;
if (key_names_table[i].name == NULL)
i = -1;
return i;
}
/*
* Find the special key with the given name (the given string does not have to
* end with NUL, the name is assumed to end before the first non-idchar).
* If the name starts with "t_" the next two characters are interpreted as a
* termcap name.
* Return the key code, or 0 if not found.
*/
int
get_special_key_code(name)
char_u *name;
{
char_u *table_name;
char_u string[3];
int i, j;
/*
* If it's <t_xx> we get the code for xx from the termcap
*/
if (name[0] == 't' && name[1] == '_' && name[2] != NUL && name[3] != NUL)
{
string[0] = name[2];
string[1] = name[3];
string[2] = NUL;
if (add_termcap_entry(string, FALSE) == OK)
return TERMCAP2KEY(name[2], name[3]);
}
else
for (i = 0; key_names_table[i].name != NULL; i++)
{
table_name = key_names_table[i].name;
for (j = 0; isidchar(name[j]) && table_name[j] != NUL; j++)
if (TO_LOWER(table_name[j]) != TO_LOWER(name[j]))
break;
if (!isidchar(name[j]) && table_name[j] == NUL)
return key_names_table[i].key;
}
return 0;
}
char_u *
get_key_name(i)
int i;
{
if (i >= KEY_NAMES_TABLE_LEN)
return NULL;
return key_names_table[i].name;
}
#ifdef USE_MOUSE
/*
* Look up the given mouse code to return the relevant information in the other
* arguments. Return which button is down or was released.
*/
int
get_mouse_button(code, is_click, is_drag)
int code;
int *is_click;
int *is_drag;
{
int i;
for (i = 0; mouse_table[i].pseudo_code; i++)
if (code == mouse_table[i].pseudo_code)
{
*is_click = mouse_table[i].is_click;
*is_drag = mouse_table[i].is_drag;
return mouse_table[i].button;
}
return 0; /* Shouldn't get here */
}
/*
* Return the appropriate pseudo mouse event token (KE_LEFTMOUSE etc) based on
* the given information about which mouse button is down, and whether the
* mouse was clicked, dragged or released.
*/
int
get_pseudo_mouse_code(button, is_click, is_drag)
int button; /* eg MOUSE_LEFT */
int is_click;
int is_drag;
{
int i;
for (i = 0; mouse_table[i].pseudo_code; i++)
if (button == mouse_table[i].button
&& is_click == mouse_table[i].is_click
&& is_drag == mouse_table[i].is_drag)
{
return mouse_table[i].pseudo_code;
}
return KE_IGNORE; /* not recongnized, ignore it */
}
#endif /* USE_MOUSE */